** Subprograms to parse options, place outside program fixed_effects 
cap program drop parse_tables
program parse_tables, sclass
	syntax[, NAMEs(str) dir(str) opt(str) commandopt(str)]
	** opt: addtext options in outreg2
	** commandopt: extra options in outreg2 
	
	sreturn local tablenames `names' 
	sreturn local tabledir `dir'
	sreturn local extratabopt `opt' 
	sreturn local tablecommandopt `commandopt' 
	
end 

cap program drop parse_save
program parse_save, sclass
	syntax[, NAMEs(str) dir(str) PARMest ]
	** parm: whether user wants to parmest data, defaults to parmest if outgraphs is specified since outgraphs requires it 
	**		parmest preserves and restores so not recommended for large data in memory, can run separately on ster files post estimation 
	
	sreturn local nameopt `names' 
	sreturn local savedir `dir' 
	sreturn local parmest `parmest' 
	
end

cap program drop parse_graphs 
program parse_graphs, sclass
	syntax[, num(str) dir(str) xlab(str) xname(str) commandopt(str) break]
	** num: myeclplot graph options, defaults to one
	** commandopt: extra options into the eclplot functions
	** break: whether user wants breaks in between graphs for viewing in GUI, default runs all graphs automatically 
	
	sreturn local graph `num'
	sreturn local graphdir `dir'
	sreturn local xlab `xlab'
	sreturn local xname `xname' 
	sreturn local graphcommandopt `commandopt' 
	sreturn local graphbreak `break' 

end 

cap program drop parse_interact
program parse_interact, sclass
	syntax, var(str) itype(str) xtype(str) symbol(str) 
	** interact(, var(group1 group2) itype (i i) xtype(c c) symbol(# ##) 
	** e.g. if x(x1 x2) but x2 is not interacted: interact(, var(group1) itype(i) xtype(c) symbol(#))
	** or alternatively, interact(, var(group1 "") itype(i "") xtype(c "") symbol(# "") 
	** Assign types after lags and leads creation 
	** Doesn't work well for discrete types so far, encouraged not to use it 
	
	sreturn local ilist `var' 
	sreturn local xtype `xtype' 
	sreturn local itype `itype'
	sreturn local isymbol `symbol' 
	
end

*** FIXED EFFECTS MAIN PROGRAM *** 
cap program drop fixed_effects
program fixed_effects
	** Description: FE Reg with all sorts of robustness checks  
	** Outputs: 1. Contemporaneous 2. Lagged 3. Cumulative effects (Derived from sum of distributed lags or using direct specification) 
	** Variables: 
	** y: Outcome y; x: Explanatory variable x and its lags (if local is vector, double quote it); controls: control variables; 
	** unit: Observation unit; year: Year; period: Period (quarter, month); cluster: Cluster standard errors; lags: Number of lags; leads: Number of leads; panel: Panel variable; time: Time variable;
	** Table options (con cum); fe: FE options (1-8); extra_fe: Extra FEs; interact: interact(, var(vector, match with x) type(i/c) symbol(#/##)); addleads: Dist Lag Graphs with leads to test pre-trends; 
	** diff: No. of periods for diff operator (Lower number of parameters estimated, SEs slightly shrink); opt: contemp distlag distlag_sum cumul(ative effects); results: load or save (default) estimates in .dta; 
	** outtables: options for tables; outgraphs: options for graphs; savereg: options for saving reg; 
	** Legacy options now included into outgraphs outtables savereg: tables dir save graph graphopt nameopt xlab xname savedir tabledir graphdir 
	** iv: Instrumental variables; extra_opt: extra options for reghdfe; eststo: apply myeststo to contemp for outputs 

	** Example
	** fixed_effects if channel_code=="`i'", ///
	** y(`v') x(log_mwq) unit(store_code_uc) year(year) period(quarter) cluster(state) ///
	** controls(loghousingp_zip3_at logunemp logpop logaw) ///
	** lags(4) leads(6) time(yq) fe(3) addleads ///
	** outtables(, name(conchanqDFM_0615_`v' cumchanqDFM_0615_`v' dlchanqDFM_0615_`v') dir(${path_out}/tables/) ///
	** opt("Channel Code", "`i'", "Controls", "X")) /// 
	** savereg(, dir(${path_out}/reg/) name(gp`i'_controls_0615)) ///
	** outgraphs(, dir(${path_out}/graphs/) num(1)) 	
	
	** Note 1: How to circumvent insufficient observations problem ( number of clusters < number of variables ) ? 
		** Go to reghdfe ado file and comment out * assert... insufficient observations
	** Note 2: To get legend of coefficients, use reghdfe, coefl
	** Note 3: If the data file is huge, do not use outgraphs with the estimation, only use it with results(load) because the command does preserve and restore
	** Note 4: Remember to put space in between extra table options 
	
	** NOTE: parmest needs to preserve the existing data set, so if the data in memory is huge, significantly slows down the code, could consider saving just as a ster file and then re-running the code with results(load) in another Stata window 
	
	syntax [if] [in] [aweight pweight fweight] [, y(str) x(str) controls(str) unit(str) year(str) ///
	period(str) cluster(namelist) lags(numlist) leads(numlist) panel(str) time(str) fe(str) extra_fe(str) /// 
	interact(str) addleads diff(numlist) opt(str) results(str) outtables(str) outgraphs(str) savereg(str) ///
	tables(str) dir(str) save EXTRATABopt(str) graph(str) graphopt(str) NAMEopt(str) xlab(str) xname(str) savedir(str) tabledir(str) graphdir(str) ///
	iv(str) EXTRA_opt(str) eststo ]
	
	*** SET-UP ***  
	
	** Setup time variables 
	if "`panel'"=="" local panel `unit' 
	cap noi tsset `panel' `time' 
	
	cap gen time1 = `time'
	cap gen time2=`time'^2
	cap gen time3=`time'^3

		** Setup outputs 
		** Parse options and output to original local names 
		if `"`outtables'"' != "" {
			parse_tables `outtables'
			local tables `s(tablenames)'
			local tabledir `s(tabledir)'
			local extratabopt `s(extratabopt)'
			local tablecommandopt `s(tablecommandopt)' 
		}
		
		if `"`savereg'"'!="" {
			parse_save `savereg' 
			local save `s(parmest)' 
			local nameopt `s(nameopt)' 
			local savedir `s(savedir)'
		}
		
		if `"`outgraphs'"'!="" {
			parse_graphs `outgraphs' 
			local graph `s(graph)'
			local graphdir `s(graphdir)'
			local xlab `s(xlab)'
			local xname `s(xname)' 
			local graphcommandopt `s(graphcommandopt)'
			local graphbreak `s(graphbreak)'
		}
		
		if `"`interact'"'!="" {
			parse_interact `interact'
			local ilist `s(ilist)'
			local itype `s(itype)' 
			local xtype `s(xtype)' 
			local isymbol `s(isymbol)' 
		}
		
	* Default: Run all of contemp, distlag, and cumul
	if "`opt'"=="" local opt contemp distlag cumul 
	* Default: Estimate
	if "`results'"=="" local results est
	
	** Tokenize table names ***
		** NOTE: distlag is 3rd due to legacy issues 
	tokenize `tables' 
	local table1 "`tabledir'`1'"
	local table2 "`tabledir'`2'" 
	local table3 "`tabledir'`3'" 
	** Tokenize variable names for file name (file name will have first variable of vector) 
	tokenize `x' 
	local x1 `1' 
				
	** Prepare local list of variables for the cumulative effects, do only if distlag/cumul specified ** 
	local cum ""
	if "`diff'"=="" local diff=1 
	
	if strpos("`opt'","distlag")>0|strpos("`opt'","cumul")>0 {
			
			di "Creating lead list"
			foreach i of numlist `leads'(`diff')1 {
				** Loop over variables in varlist local 
				foreach v in `x' {
					** local f`i'x "" 
					local ii=`i'
					cap gen f`i'`v'=f`i'.`v' 
					cap gen f`ii's`diff'`v'=f`ii'.s`diff'.`v'
					* local lead_list`i' `lead_list`i'' f`i'`v'
					* local dle`v' `dle`v'' l`ii'd`v' 
					local lead_list `lead_list' f`i'`v'
					if "`addleads'"!="" local cum `cum' f`ii's`diff'`v' 
				}
			}
			
			
			if "`iv'"!="" {
				foreach i of numlist `leads'(`diff')1 {
					** Loop over variables in varlist local 
					foreach v in `iv' {
						** local f`i'x "" 
						local ii=`i'
						cap gen f`i'`v'=f`i'.`v' 
						cap gen f`ii's`diff'`v'=f`ii'.s`diff'.`v'
						* local lead_list`i' `lead_list`i'' f`i'`v'
						* local dle`v' `dle`v'' l`ii'd`v' 
						local iv_lead_list `iv_lead_list' f`i'`v'
						if "`addleads'"!="" local iv_cum `iv_cum' f`ii's`diff'`v' 
					}
				}
			}
		
		* Loop over number of lags 
		di "Creating lag list"
		foreach i of numlist 1(`diff')`lags' {
			* Loop over variables in varlist local 
			foreach v in `x' { 
				* local l`i'x ""
				local ii=`i'-1 
				local iii=`ii'+`diff'
				cap gen l`i'`v'=l`i'.`v'
				cap gen l`ii's`diff'`v'=l`ii'.s`diff'.`v'
				* local lag_list`i' `lag_list`i'' l`i'`v'
				* local dla`v' `dla`v'' l`ii'd`v' 
				local lag_list `lag_list' l`iii'`v' 
				local cum `cum' l`ii's`diff'`v'
			}	
		}
		
		if "`iv'"!="" {
			foreach i of numlist 1(`diff')`lags' {
				* Loop over variables in varlist local 
				foreach v in `iv' { 
					* local l`i'x ""
					local ii=`i'-1 
					local iii=`ii'+`diff'
					cap gen l`i'`v'=l`i'.`v'
					cap gen l`ii's`diff'`v'=l`ii'.s`diff'.`v'
					* local lag_list`i' `lag_list`i'' l`i'`v'
					* local dla`v' `dla`v'' l`ii'd`v' 
					local iv_lag_list `iv_lag_list' l`iii'`v' 
					local iv_cum `iv_cum' l`ii's`diff'`v'
				}	
			}
		}
		
		* Ordering: all cumulative responses at the end 
		foreach v in `x' {
			* local dla`lags' `dla`lags'' l`lags'`v'
			local cum `cum' l`lags'`v'
		}
			
		* Allow for interactions  
		* Need to lead and lag the ilist variables as well  

		* di "`ilist'"
		if "`interact'"!="" {
				
				di "Creating interacted lead list"
				* Lead list for interacted terms
				foreach i of numlist `leads'(`diff')1 {
					local t=1
					* Elementwise combo
					foreach v in `ilist' {
						local ii=`i'
						cap gen f`i'`v'=f`i'.`v'
						cap gen f`ii's`diff'`v'=f`ii'.s`diff'.`v'
						* local ilead_list`i' `ilead_list`i'' f`i'`v'
						*local ilead_list `ilead_list' f`i'`v'
						* if "`addleads'"!="" local icum `icum' f`ii's`diff'`v' 				
						
						local itype`t': word `t' of `itype'
						local ilist`t': word `t' of `ilist'
						local isymbol`t': word `t' of `isymbol'
						local xtype`t': word `t' of `xtype' 
						local x`t': word `t' of `x' 
						local ilead_list `ilead_list' `itype`t''.f`i'`v'`isymbol`t''`xtype`t''.f`i'`x`t''
						if "`addleads'"!="" local icum `icum' `itype`t''.f`ii's`diff'`v'`isymbol`t''`xtype`t''.f`ii's`diff'`x`t''
						local ++t
					}
				}
				* di "`ilead_list'" 
				
				di "Creating interacted lag list"
				* Lag list for interacted terms
					foreach i of numlist 1(`diff')`lags' {
					local t=1 
					* Elementwise combo
					* Loop over variables in varlist local 
					foreach v in `ilist' {
							* local l`i'x ""
							local ii=`i'-1 
							local iii=`ii'+`diff'
							cap gen l`i'`v'=l`i'.`v'
							cap gen l`ii's`diff'`v'=l`ii'.s`diff'.`v'
							* local ilag_list`i' `ilag_list`i'' l`i'`v'
							* local dla`v' `dla`v'' l`ii'd`v' 
							*local ilag_list `ilag_list' l`iii'`v' 
							*local icum `icum' l`ii's`diff'`v'
							
							local itype`t': word `t' of `itype'
							local ilist`t': word `t' of `ilist'
							local isymbol`t': word `t' of `isymbol'
							local xtype`t': word `t' of `xtype' 
							local x`t': word `t' of `x' 
							local ilag_list `ilag_list' `itype`t''.l`iii'`v'`isymbol`t''`xtype`t''.l`iii'`x`t''
							local icum `icum' `itype`t''.l`ii's`diff'`v'`isymbol`t''`xtype`t''.l`ii's`diff'`x`t''
							local ++t
						}	
					}
					* di "`ilag_list'" 

			local lag_list `ilag_list'
			local lead_list `ilead_list'
			local cum `icum'
		}
	}
	
		* di "`ilist'"
		if "`interact'"!="" {				
					* Contemp
						local t=1
						foreach v in `ilist' {
							local itype`t': word `t' of `itype'
							local ilist`t': word `t' of `ilist'
							local isymbol`t': word `t' of `isymbol'
							local xtype`t': word `t' of `xtype' 
							local x`t': word `t' of `x' 
							* local dla`lags' `dla`lags'' l`lags'`v'
							local ix `ix' `itype`t''.`v'`isymbol`t''`xtype`t''.`x`t''
							local ++t 
						}
						* di "`ix'" 
						
			local x `ix'
		}
	
		* Eliminate lead list if leads = 0, alternatively just drop the addleads option for cumul
		if "`leads'"=="0" local lead_list 
		* Eliminate lag list if lags = 0 (Test for leads alone without the lags) 
		if "`lags'"=="0" local lag_list 
		
	* If no interact, just keep key variables (option dropped, keep(`keepcumx'))
	* If interacted, just let them sit around (eliminate manually for convenience)
	* local keepx "" 
	if "`interact'"=="" local keepx `x' 

	*** GRAPHS *** 
	* Default: graph number 1
	if `"`outgraphs'"'!=""&"`graph'"=="" local graph 1
	* Eclplot commands
	local eclplot_commands `"eplot(con) ciopts(recast(rconnected) lp(dash)) graphregion(color(white)) yline(0,lp(dash))"'
	* Graphopt/nameopt option 

	if "`nameopt'"!="" local nameopt "_`nameopt'"
	if "`graphopt'"!="" local nameopt "_`graphopt'"
	
		* Setup xlab (Event time variable, not x vector) 
		local i=0
		local xlablist ""
		if "`addleads'"!="" { 
			local nleads=-`leads'
			foreach n of numlist `nleads'(`diff')-1 {
				local i=`i'+1
				local xlablist `xlablist' `i' "`n'"
			}
		}
		foreach n of numlist 0(`diff')`lags' {
			local i=`i'+1
			if `n'==0 local xline=`i' 
			local xlablist `xlablist' `i' "`n'"		
		}
		
	** Graph requires save as parmest, if outgraphs is set, default to saving by parmest
	if "`graph'"!="" local save parmest
	* Correction for old code related to graph directory
	if "`dir'"!="" local graphdir `dir' 
	
*** RUN REGHDFE ***
	
if "`iv'"=="" { 
	* Default: run all specifications 
	if "`fe'"=="" local fe "00 1 2 3 4 5 6 7 8 9" 
		
foreach i in 00 1 2 3 4 5 6 7 8 9 {
	if strpos("`fe'","`i'")>0 {
		
		if strpos("`i'","00")>0 {
			local di "Default"
		}
		
		if strpos("`i'","1")>0 {
			local absorb "`unit' `year'"
			local di "Unit year FE" 
			local fe_opt "fe1(`unit') fe2(`year')" 
		}
		
		if strpos("`i'","2")>0 {
			local absorb "`unit' `year' `period'"
			local di "Unit year period FE" 
			local fe_opt "fe1(`unit') fe2(`year') fe3(`period')" 
		}

		if strpos("`i'","3")>0 {
			local absorb "`unit' `year'#`period'"
			local di "Unit year-period FE" 
			local fe_opt "fe1(`unit') fe2(`year'-`period')"
		}
		
		if strpos("`i'","4")>0 {
			local absorb "`unit' `unit'#`period' `year'"
			local di "Unit-period year FE" 
			local fe_opt "fe1(`unit'-`period') fe2(`year')"
		}
		
		if strpos("`i'","5")>0 {
			local absorb "`unit' `unit'#`period' `year'#`period'"
			local di "Unit-period year-period FE" 
			local fe_opt "fe1(`unit'-`period') fe2(`year'-`period')"
		}

		if strpos("`i'","6")>0 {
			local absorb "`unit' `unit'#`period' `year'#`period' `unit'#c.time1"
			local di "Unit-period unit-specific linear trend FE" 
			local fe_opt "fe1(`unit'-`period') fe2(`year'-`period') trend(1)"
		}
		
		if strpos("`i'","7")>0 {
			local absorb "`unit' `unit'#`period' `year'#`period' `unit'#c.time1 `unit'#c.time2"
			local di "Unit-period unit-specific quadratic trend FE" 
			local fe_opt "fe1(`unit'-`period') fe2(`year'-`period') trend(2)"
		}
		
		if strpos("`i'","8")>0 {
			local absorb "`unit' `unit'#`period' `year'#`period' `unit'#c.time1 `unit'#c.time2 `unit'#c.time3"
			local di "Unit-period unit-specific cubic trend FE" 
			local fe_opt "fe1(`unit'-`period') fe2(`year'-`period') trend(3)"
		}
		
		if strpos("`i'","9")>0 {
			local absorb "`unit' `unit'#`period' `unit'#`year'"
			local di "Unit-period unit-year FE" 
			local fe_opt "fe1(`unit'-`period') fe2(`unit'-`year')" 
		}
	

	di "`di'"
	if strpos("`opt'","contemp")>0 {
		di "`di': Contemporaneous" 
		if strpos("`results'","est")>0 {
			cap noi reghdfe `y' `x' `controls' `if' `in' [`weight'`exp'], absorb(`absorb' `extra_fe') vce(cluster `cluster') `extra_opt' 
			cap noi est save "`savedir'`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'" , replace
		} 
		if strpos("`results'","load")>0 {
			cap noi est use  "`savedir'`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'" 
			cap noi reghdfe
		}
		cap noi myoutreg if "`table1'"!="", file("`table1'") `fe_opt' extra(`extratabopt') ///
		extra_commands(`tablecommandopt') 
		
		if "`eststo'"!="" myeststo 
		
		if "`save'"!="" {
			parmest, saving("`savedir'`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'" , replace) 
		} 
	}
	
	if strpos("`opt'","distlag")>0 {
		di "`di': Distributed lags" 
		if strpos("`results'","est")>0 {
			cap noi reghdfe `y' `lead_list' `x' `lag_list'  `controls' `if' `in' [`weight'`exp'], absorb(`absorb' `extra_fe') ///
			vce(cluster `cluster') `extra_opt' 
			cap noi est save "`savedir'd_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'" , replace
		}
		if strpos("`results'","load")>0 {
			cap noi est use  "`savedir'd_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'" 
			cap noi reghdfe
		}
		cap noi myoutreg if "`table3'"!="", file("`table3'") `fe_opt' extra(`extratabopt') ///
		extra_commands(`tablecommandopt') 

		cap testparm `lead_list'
		cap local lead_p=`r(p)'

		if "`save'"!="" {
			parmest, saving("`savedir'd_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'" , replace) 
		}
		if "`graph'"!="" {		
			preserve 
			use "`savedir'd_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'" , clear
			local vec: word count `x'
			* Keep and plot only interact terms if interacting
			if "`interact'"!="" {
				keep if strpos(parm,"#")				
			}
			foreach n of numlist 1/6 {
				if strpos("`graph'","`n'")>0 local g`n' "`graphdir'd`n'_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' "
			}
			myeclplot, byvar(`g1') con(`g2') cum(`g3') concum(`g4') concum2(`g5') all(`g6') xdim(`vec') leads(`leads') lags(`lags') `addleads' ///
			diff(`diff') xlab(`"`xlab'"') xname(`xname') extra_commands(`graphcommandopt')
			restore 
			
			if strpos("`results'","load")&"`graphbreak'"!="">0 {
				pause on 
				pause 
			}
			
			}	
	}
	
	if strpos("`opt'","distlag_sum")>0 {
		di "`di': Distlag Sum" 
		
		if strpos("`results'","load")>0 {
			cap noi est use  "`savedir'd_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'" 
			cap noi reghdfe
		}
		
		cap est store temp 
		
		local lincomlist
		
		local distlag_list `lead_list' `x' `lag_list'
		if "`interact'"!="" local distlag_list=subinstr("`distlag_list'", "##","#",.)
		
		foreach v in `distlag_list' {
			
			if "`lincomlist'"!="" local lincomlist "`lincomlist'+`v'" 
			if "`lincomlist'"=="" local lincomlist `v' 

			lincomest `lincomlist' 
			
			if "`interact'"!="" local v=subinstr("`v'","#","_x_",.)
			if "`interact'"!="" local v=subinstr("`v'",".","",.)
			cap parmest, saving("`savedir'ds_`v'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'_parmest", replace)
			cap est restore temp
		}
		
		if "`save'"!="" {		
			preserve
			clear
			foreach v in `distlag_list' {
				if "`interact'"!="" local v=subinstr("`v'","#","_x_",.)
				if "`interact'"!="" local v=subinstr("`v'",".","",.)
				append using "`savedir'ds_`v'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'_parmest"
				cap replace parm="`v'" if parm=="(1)"
				erase "`savedir'ds_`v'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'_parmest.dta"
			}
			
			save "`savedir'ds_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'", replace
			restore
		}
	
		if "`graph'"!="" {
			preserve
			use "`savedir'ds_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'" , clear
			local vec: word count `x' 
			foreach n of numlist 1/6 {
				if strpos("`graph'","`n'")>0 local g`n' "`graphdir'ds`n'_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' "
			}
			myeclplot, byvar(`g1') con(`g2') cum(`g3') concum(`g4') concum2(`g5') all(`g6') xdim(`vec') leads(`leads') lags(`lags') `addleads' ///
			diff(`diff') xlab(`"`xlab'"') xname(`xname') extra_commands(`graphcommandopt')
			
			if strpos("`results'","load")&"`graphbreak'"!="">0 {
				pause on 
				pause 
			}
			
			restore 
		}
	}
	  
	
	if strpos("`opt'","cumul")>0 {
		di "`di': Cumulative Effect" 
		if strpos("`results'","est")>0 {
			cap noi reghdfe `y' `cum' `controls' `if' `in' [`weight'`exp'], absorb(`absorb' `extra_fe') vce(cluster `cluster') `extra_opt'  
			cap noi est save "`savedir'c_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'" , replace
		}
		if strpos("`results'","load")>0 {
			cap noi est use  "`savedir'c_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'" 
			cap noi reghdfe
		}

		cap if `lead_p'>0.05 local lead_opt "y"
		cap if `lead_p'<=0.05 local lead_opt "n"
		
		cap noi myoutreg if "`table2'"!="", file("`table2'") `fe_opt' lead(`lead_opt') extra(`extratabopt') ///
		extra_commands(`tablecommandopt')
			
		if "`save'"!="" {
			parmest, saving("`savedir'c_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'" , replace) 
		}
		if "`graph'"!="" {
			preserve
			use "`savedir'c_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'" , clear
			local vec: word count `x' 
			foreach n of numlist 1/6 {
				if strpos("`graph'","`n'")>0 local g`n' "`graphdir'c`n'_`x1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' "
			}
			myeclplot, byvar(`g1') con(`g2') cum(`g3') concum(`g4') concum2(`g5') all(`g6') xdim(`vec') leads(`leads') lags(`lags') `addleads' ///
			diff(`diff') xlab(`"`xlab'"') xname(`xname') extra_commands(`graphcommandopt')
			
			if strpos("`results'","load")&"`graphbreak'"!="">0 {
				pause on 
				pause 
			}
			
			restore 
		}
	}
  }	
 }
}

*** IV VERSION *** 

if "`iv'"!="" { 
	tokenize "`iv'"
	local z1 `1' 
	* Default: run all specifications 
	if "`fe'"=="" local fe "00 1 2 3 4 5 6 7 8 9" 
		
	foreach i in 00 1 2 3 4 5 6 7 8 9 {
		if strpos("`fe'","`i'")>0 {

			if strpos("`i'","00")>0 {
				local di "Default" 
			}
			
			if strpos("`i'","1")>0 {
				local absorb "`unit' `year'"
				local di "Unit year FE" 
				local fe_opt "fe1(`unit') fe2(`year')" 
			}
			
			if strpos("`i'","2")>0 {
				local absorb "`unit' `year' `period'"
				local di "Unit year period FE" 
				local fe_opt "fe1(`unit') fe2(`year') fe3(`period')" 
			}

			if strpos("`i'","3")>0 {
				local absorb "`unit' `year'#`period'"
				local di "Unit year-period FE" 
				local fe_opt "fe1(`unit') fe2(`year'-`period')"
			}
			
			if strpos("`i'","4")>0 {
				local absorb "`unit' `unit'#`period' `year'"
				local di "Unit-period year FE" 
				local fe_opt "fe1(`unit'-`period') fe2(`year')"
			}
			
			if strpos("`i'","5")>0 {
				local absorb "`unit' `unit'#`period' `year'#`period'"
				local di "Unit-period year-period FE" 
				local fe_opt "fe1(`unit'-`period') fe2(`year'-`period')"
			}
			
			if strpos("`i'","6")>0 {
				local absorb "`unit' `unit'#`period' `year'#`period' `unit'#c.time1"
				local di "Unit-period unit-specific linear trend FE" 
				local fe_opt "fe1(`unit'-`period') fe2(`year'-`period') trend(1)"
			}
			
			if strpos("`i'","7")>0 {
				local absorb "`unit' `unit'#`period' `year'#`period' `unit'#c.time1 `unit'#c.time2"
				local di "Unit-period unit-specific quadratic trend FE" 
				local fe_opt "fe1(`unit'-`period') fe2(`year'-`period') trend(2)"
			}
			
			if strpos("`i'","8")>0 {
				local absorb "`unit' `unit'#`period' `year'#`period' `unit'#c.time1 `unit'#c.time2 `unit'#c.time3"
				local di "Unit-period unit-specific cubic trend FE" 
				local fe_opt "fe1(`unit'-`period') fe2(`year'-`period') trend(3)"
			}
			
			if strpos("`i'","9")>0 {
				local absorb "`unit' `unit'#`period' `unit'#`year'"
				local di "Unit-period unit-year FE" 
				local fe_opt "fe1(`unit'-`period') fe2(`unit'-`year')" 
			}
	
	** Fix issue with empty weights when IV'ing (does not occur with OLS) 
	if "`weight'"!="" local weightexp [`weight'`exp']

	di "`di'"
	if strpos("`opt'","contemp")>0 {
		di "`di': Contemporaneous" 
		if strpos("`results'","est")>0 {
			cap noi reghdfe `y' `controls' (`x' = `iv') `if' `in' `weightexp', absorb(`absorb' `extra_fe') vce(cluster `cluster') `extra_opt' 
			cap noi est save `savedir'`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' , replace
			
			if strpos("`extra_opt'","first")>0 {
				estimates restore reghdfe_first1 
				cap noi est save `savedir'`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'_first, replace			
			}
			
			if strpos("`extra_opt'","ols")>0 {
				estimates restore reghdfe_ols 
				cap noi est save `savedir'`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'_ols, replace			
			}

			cap noi est use `savedir'`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' 

		} 
		
		if strpos("`results'","load")>0 {
			cap noi est use `savedir'`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' 
			cap noi reghdfe
		}

		if strpos("`extra_opt'","first")>0 {
			cap noi est use `savedir'`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'_first  			
			cap noi myoutreg if "`table1'"!="", file("`table1'_first") `fe_opt' extra(`extratabopt') ///
			extra_commands(`tablecommandopt') 		
		}
		
		** Saves ols with IV 
		if strpos("`extra_opt'","ols")>0 {
			cap noi est use `savedir'`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'_ols  					
			cap noi myoutreg if "`table1'"!="", file("`table1'") `fe_opt' extra(`extratabopt') ///
			extra_commands(`tablecommandopt') 	
			if "`eststo'"!="" myeststo			
		}
		
		cap noi est use `savedir'`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' 
		local widstat = string(`e(widstat)', "%12.3f")
		if "`extratabopt'"!="" local extratabopt `", `extratabopt'"'
		cap noi myoutreg if "`table1'"!="", file("`table1'") `fe_opt' extra("First-stage F-stat", "`widstat'" `extratabopt') ///
		extra_commands(`tablecommandopt') 
		if "`eststo'"!="" myeststo

		
		if "`save'"!="" {
			parmest, saving(`savedir'`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' , replace) 
		}

	}
	
	if strpos("`opt'","distlag")>0 {
		di "`di': Distributed lags" 
		if strpos("`results'","est")>0 {
			cap noi reghdfe `y' `controls' (`lead_list' `x' `lag_list' = `iv_lead_list' `iv' `iv_lag_list') ///
			`if' `in' `weightexp', absorb(`absorb' `extra_fe') `extra_opt' ///
			vce(cluster `cluster') 
			cap noi est save `savedir'd_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' , replace
		}
		if strpos("`results'","load")>0 {
			cap noi est use  `savedir'd_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' 
			cap noi reghdfe
		}
		cap noi myoutreg if "`table3'"!="", file("`table3'") `fe_opt' extra(`extratabopt') ///
		extra_commands(`tablecommandopt') 

		cap testparm `lead_list'
		cap local lead_p=`r(p)'

		if "`save'"!="" {
			parmest, saving(`savedir'd_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' , replace) 
		}
		if "`graph'"!="" {		
			preserve 
			use `savedir'd_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' , clear
			local vec: word count `x'
			* Keep and plot only interact terms if interacting
			if "`interact'"!="" {
				keep if strpos(parm,"#")				
			}
			foreach n of numlist 1/6 {
				if strpos("`graph'","`n'")>0 local g`n' "`graphdir'd`n'_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' "
			}
			myeclplot, byvar(`g1') con(`g2') cum(`g3') concum(`g4') concum2(`g5') all(`g6') xdim(`vec') leads(`leads') lags(`lags') `addleads' ///
			diff(`diff') xlab(`"`xlab'"') xname(`xname') extra_commands(`graphcommandopt')
			restore 
			
			if strpos("`results'","load")>0 {
				pause on 
				pause 
			}
			
			}	
	}
	
	if strpos("`opt'","distlag_sum")>0 {
		di "`di': Distlag Sum" 
		
		if strpos("`results'","load")>0 {
			cap noi est use  `savedir'd_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' 
			cap noi reghdfe
		}
		
		cap est store temp 
		
		local lincomlist
		
		local distlag_list `lead_list' `x' `lag_list'
		if "`interact'"!="" local distlag_list=subinstr("`distlag_list'", "##","#",.)
		
		foreach v in `distlag_list' {
			
			if "`lincomlist'"!="" local lincomlist "`lincomlist'+`v'" 
			if "`lincomlist'"=="" local lincomlist `v' 

			lincomest `lincomlist' 
			
			if "`interact'"!="" local v=subinstr("`v'","#","_x_",.)
			if "`interact'"!="" local v=subinstr("`v'",".","",.)
			cap parmest, saving(`savedir'ds_`v'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'_parmest, replace)
			cap est restore temp
		}
		
		if "`save'"!="" {		
			preserve
			clear
			foreach v in `distlag_list' {
				if "`interact'"!="" local v=subinstr("`v'","#","_x_",.)
				if "`interact'"!="" local v=subinstr("`v'",".","",.)
				append using "`savedir'ds_`v'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'_parmest"
				cap replace parm="`v'" if parm=="(1)"
				erase "`savedir'ds_`v'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt'_parmest.dta"
			}
			
			save `savedir'ds_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt', replace
			restore
		}
	
		if "`graph'"!="" {
			preserve
			use `savedir'ds_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' , clear
			local vec: word count `x' 
			foreach n of numlist 1/6 {
				if strpos("`graph'","`n'")>0 local g`n' "`graphdir'ds`n'_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' "
			}
			myeclplot, byvar(`g1') con(`g2') cum(`g3') concum(`g4') concum2(`g5') all(`g6') xdim(`vec') leads(`leads') lags(`lags') `addleads' ///
			diff(`diff') xlab(`"`xlab'"') xname(`xname') extra_commands(`graphcommandopt')
			
			if strpos("`results'","load")>0 {
				pause on 
				pause 
			}
			
			restore 
		}
	}
	  
	
	if strpos("`opt'","cumul")>0 {
		di "`di': Cumulative Effect" 
		if strpos("`results'","est")>0 {
			cap noi reghdfe `y' `controls' (`cum' = `iv_cum') `if' `in' `weightexp', absorb(`absorb' `extra_fe') vce(cluster `cluster') `extra_opt'  
			cap noi est save `savedir'c_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' , replace
		}
		if strpos("`results'","load")>0 {
			cap noi est use  `savedir'c_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' 
			cap noi reghdfe
		}

		cap if `lead_p'>0.05 local lead_opt "y"
		cap if `lead_p'<=0.05 local lead_opt "n"
		
		cap noi myoutreg if "`table2'"!="", file("`table2'") `fe_opt' lead(`lead_opt') extra(`extratabopt') ///
		extra_commands(`tablecommandopt')
			
		if "`save'"!="" {
			parmest, saving(`savedir'c_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' , replace) 
		}
		if "`graph'"!="" {
			preserve
			use `savedir'c_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' , clear
			local vec: word count `x' 
			foreach n of numlist 1/6 {
				if strpos("`graph'","`n'")>0 local g`n' "`graphdir'c`n'_`x1'_`z1'_`y'_fe`i'_`leads'`lags'_`diff'`nameopt' "
			}
			myeclplot, byvar(`g1') con(`g2') cum(`g3') concum(`g4') concum2(`g5') all(`g6') xdim(`vec') leads(`leads') lags(`lags') `addleads' ///
			diff(`diff') xlab(`"`xlab'"') xname(`xname') extra_commands(`graphcommandopt')
			
			if strpos("`results'","load")>0 {
				pause on 
				pause 
			}
			
			restore 
		}
	}
  }	
 }
}


end
